import java.net.DatagramSocket;
import java.net.SocketException;

public class MainClass {
	public static final int BUF_SIZE = 1024;	
	public static final int PORT_LOWER_BOUND = 1024;
	public static final int PORT_UPPER_BOUND = 49151;	
	
	// TIME_INTERVAL defines the length (ms) for waiting to send the same request again. 
	public static int TIME_INTERVAL = 3000; 
	public static int MAX_TIME_TRYING = 5;
	
	static void threadMessage(String message) {
        String threadName =
            Thread.currentThread().getName();
        System.out.format("%s: %s%n",
                          threadName,
                          message);
    }
	
	public static void main(String[] args) throws InterruptedException {
		DatagramSocket requestSocket = null;
		DatagramSocket exchangeSocket = null;
		try {
			// create sockets and bind to ports p and p+1 (if available)
			int p;
			for (p = PORT_LOWER_BOUND; p <= PORT_UPPER_BOUND - 1; p++) {
				try {
					requestSocket = new DatagramSocket(p);
					exchangeSocket = new DatagramSocket(p+1);
					System.out.println("Successfully bind to ports " + requestSocket.getLocalPort() + " and " + exchangeSocket.getLocalPort());
					break;
				} catch (SocketException e) {
					System.out.println("Socket binding: ports " + p + " and " + (p+1) + " didn't work, trying the next p...");
					if (requestSocket != null && !requestSocket.isClosed()) requestSocket.close();
					if (exchangeSocket != null && !exchangeSocket.isClosed()) exchangeSocket.close();
				}
			}
			
			if (p == PORT_UPPER_BOUND) {
				System.out.println("Socket binding failed. No two consecutive ports available. Exiting...");
			} else {
				Thread mrt = new MainRequestThread(requestSocket, args[0], Integer.parseInt(args[1]));
				Thread met = new MainExchangeThread(exchangeSocket);
				mrt.start();
				met.start();
				mrt.join();
			}
		} finally {
			// note that closing requestSocket will generate an socket exception
			// in WaitResponseThread, causing it to terminate
			if (requestSocket != null && !requestSocket.isClosed()) requestSocket.close();
			if (exchangeSocket != null && !exchangeSocket.isClosed()) exchangeSocket.close();			
		}
	}
}
